#ifndef INP_TO_CDB_CONVERTOR
#define INP_TO_CDB_CONVERTOR

#include <string>
#include <vector>
#include <map>
#include "convertor.h"

class InpToCdbConvertor: public Convertor {
// 节点数据结构
struct Node {
    int id;
    double x;
    double y;
    double z;
    std::string fromString;
};

// 单元数据结构
struct Element {
    int id;
    std::string type;
    std::vector<int> nodes;
    std::string fromString;
};

struct Elset {
    std::string id;
    std::vector<int> elements;
};

struct SolidSection {
    std::string elsetId;
    std::string materialId;
};

struct ShellSection {
    std::string elsetId;
    std::string materialId;
    double thickness;
};

struct Nset {
    std::string nsetName;
    std::vector<int> nodes;
};

struct Meterial {
    std::string name;
    double conductivity = -1.0;
    std::map<double, double> conductivities;
    double density = -1.0;
    double elasticityModulus = -1.0;
    double poissonRatio = -1.0;
    double expansion = -1.0;
    std::map<double, double> expansions;
    double specificHeat = -1.0;
};

struct Boundary {
    std::string nsetName;
    int from;
    int to;
};

struct Dload {
    std::string nsetName;
    std::string dloadName;
    double xLoad;
    double yLoad;
    double zLoad;
};

public:
    InpToCdbConvertor();
    virtual ~InpToCdbConvertor();
    virtual int convert(const std::string &inpPath, const std::string &cdbPath) override;

private:
    int parseInpFile(const std::string& path);
    void parseNode(const std::string& line);
    void parseElement(const std::string& line, const std::string &elemType);
    void parseNset(const std::string& line, const std::string &nsetName);
    void parseMeterial(const std::string& line, const std::string &meterialName, const std::string &propertyType);
    void parseElset(const std::string& line, std::map<std::string, std::string> parameters);
    void parseSolidSection(const std::string& line, std::map<std::string, std::string> parameters);
    void parseShellSection(const std::string& line, std::map<std::string, std::string> parameters);
    void parseConductivity(const std::string &line, const std::string &materialName);
    void parseDensity(const std::string &line, const std::string &materialName);
    void parseElastic(const std::string &line, const std::string &materialName);
    void parseExpansion(const std::string &line, const std::string &materialName);
    void parseSpecificHeat(const std::string &line, const std::string &materialName);
    void parseBoundary(const std::string &line);
    void parseDload(const std::string &line);
    std::string parseElemType(const std::string& line);
    std::string parseNsetName(const std::string& line);
    std::string parseMaterialName(const std::string& line);

    int generateCdbFile(const std::string &path);
    std::string ElementC3D20ToSOLID186(const Element &elem);
    std::string ElementS3_4ToSOLID181(const Element &elem);

    std::string getSectionType(const std::string& line);
    void trim(std::string& s);

    std::map<std::string, std::string> getParamMap(const std::string& line);
    int extractTrailingDigits(const std::string& str);

private:
    std::vector<Node> nodes;
    std::vector<Element> elements;
    std::vector<Elset> elsets;
    std::vector<Nset> nsets;
    std::vector<Meterial> meterials;
    std::vector<SolidSection> solidSections;
    std::vector<ShellSection> shellSections;
    Dload dload;
    std::vector<Boundary> boundaries;
    std::map<int, int> elementTypeMap; // 单元类型映射表
};

#endif

